package com.zhijian.websocket;

import com.alibaba.fastjson.JSON;
import com.zhijian.entity.ChatMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocket/customerService/{userId}")
@Component
@Slf4j
public class CustomerServiceWebSocket {
    
    // 用来存储每个客户端对应的WebSocket对象
    private static Map<String, Session> clients = new ConcurrentHashMap<>();
    
    // 用来存储离线消息，key是接收者的userId，value是消息列表
    private static Map<String, List<ChatMessage>> offlineMessages = new ConcurrentHashMap<>();
    
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        clients.put(userId, session);
        log.info("有新的客户端连接，userId：{}, 当前连接数：{}", userId, clients.size());
        
        // 检查是否有离线消息，如果有则发送
        List<ChatMessage> messages = offlineMessages.get(userId);
        if (messages != null && !messages.isEmpty()) {
            messages.forEach(message -> {
                try {
                    session.getBasicRemote().sendText(JSON.toJSONString(message));
                } catch (IOException e) {
                    log.error("发送离线消息失败：{}", e.getMessage());
                }
            });
            // 发送完后清空该用户的离线消息
            offlineMessages.remove(userId);
        }
    }
    
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        clients.remove(userId);
        log.info("有客户端断开连接，userId：{}, 当前连接数：{}", userId, clients.size());
    }
    
    @OnMessage
    public void onMessage(String message, @PathParam("userId") String userId) {
        log.info("收到客户端消息，userId：{}，消息：{}", userId, message);
        ChatMessage chatMessage = JSON.parseObject(message, ChatMessage.class);
        
        // 设置消息时间
        chatMessage.setCreateTime(new Date());
        
        String toUserId = chatMessage.getToUserId();
        
        // 如果接收者在线，直接发送
        Session receiverSession = clients.get(toUserId);
        if (receiverSession != null && receiverSession.isOpen()) {
            sendMessageTo(chatMessage, toUserId);
        } else {
            // 如果接收者不在线，存储为离线消息
            storeOfflineMessage(chatMessage, toUserId);
        }
    }
    
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket发生错误：{}", error.getMessage());
    }
    
    // 发送消息给指定用户
    private void sendMessageTo(ChatMessage message, String toUserId) {
        Session session = clients.get(toUserId);
        if(session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(JSON.toJSONString(message));
            } catch (IOException e) {
                log.error("发送消息失败：{}", e.getMessage());
                // 如果发送失败，存储为离线消息
                storeOfflineMessage(message, toUserId);
            }
        } else {
            // 如果用户不在线，存储为离线消息
            storeOfflineMessage(message, toUserId);
        }
    }
    
    // 存储离线消息
    private void storeOfflineMessage(ChatMessage message, String toUserId) {
        offlineMessages.computeIfAbsent(toUserId, k -> new ArrayList<>()).add(message);
        log.info("存储离线消息，接收者：{}，消息：{}", toUserId, message);
    }
    
    // 获取用户的离线消息
    public List<ChatMessage> getOfflineMessages(String userId) {
        return offlineMessages.getOrDefault(userId, new ArrayList<>());
    }
    
    // 清除用户的离线消息
    public void clearOfflineMessages(String userId) {
        offlineMessages.remove(userId);
    }
} 